from typing import TypeVar, Generic, List

T = TypeVar('T')

class Stack(Generic[T]):
    def __init__(self, name:str) -> None:
        self.name = name
        self._container:list[T] = []

    def push(self, item:T) -> None:
        self._container.append(item)

    def pop(self) -> T:
        return self._container.pop()

    def __repr__(self) -> str:
        return repr(self._container)


def hanoi(begin:Stack[int], end:Stack[int], temp:Stack[int], n:int) -> None:
    print(f"begin {begin.name} end {end.name} temp {temp.name} n {n}")
    if n == 1:
        item = begin.pop()
        end.push(item)
        print(f"{begin.name} -> {end.name}: {item}")
    else:
        hanoi(begin, temp, end, n-1)
        hanoi(begin, end, temp, 1)
        hanoi(temp, end, begin, n-1)



if __name__ == "__main__":
    num_discs:int = 3
    tower_a: Stack[int] = Stack("a")
    tower_b: Stack[int] = Stack("b")
    tower_c: Stack[int] = Stack("c")
    for i in range(1, num_discs+1):
        tower_a.push(i)

    hanoi(tower_a, tower_c, tower_b, num_discs)

    print(tower_a)
    print(tower_b)
    print(tower_c)

